package com.ruoyi.basebill.service.impl.billIssue.util;

import com.ruoyi.basebill.domain.TWfzRemuneration;
import com.ruoyi.basebill.domain.TWfzRemunerationentry;
import com.ruoyi.basebill.domain.WfzGzff;
import com.ruoyi.basebill.domain.WfzGzffentry;
import com.ruoyi.basebill.mapper.TWfzRemunerationMapper;
import com.ruoyi.basebill.service.IWfzGzffService;
import com.ruoyi.basebill.service.IWfzGzftService;
import com.ruoyi.basebill.service.IWfzGzjtService;
import com.ruoyi.basebill.service.exception.DataNullException;
import com.ruoyi.basebill.service.impl.WfzGzffServiceImpl;
import com.ruoyi.basebill.service.impl.WfzGzftServiceImpl;
import com.ruoyi.basebill.service.impl.WfzGzjtServiceImpl;
import com.ruoyi.basebill.service.impl.WfzJtgzflServiceImpl;
import com.ruoyi.basedata.domain.WfzBank;
import com.ruoyi.basedata.domain.WfzBankentry;
import com.ruoyi.basedata.domain.WfzBaseunit;
import com.ruoyi.basedata.domain.WfzPerson;
import com.ruoyi.basedata.mapper.WfzBankMapper;
import com.ruoyi.basedata.service.IWfzBankService;
import com.ruoyi.basedata.service.IWfzBaseunitService;
import com.ruoyi.basedata.service.impl.WfzPersonServiceImpl;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.pushEnum.BillEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @projectName: wfz
 * @package: com.ruoyi.basebill.service.impl.billIssue.util
 * @className: GzUtil
 * @author: Eric
 * @description: TODO
 * @date: 2023/3/3 15:40
 * @version: 1.0
 */
@Component
public class GzUtil {
    @Autowired
    private TWfzRemunerationMapper tWfzRemunerationMapper;
    //单据下发工具类
    @Autowired
    private BillIssueUtil billIssueUtil;
    //工资发放服务层接口
    @Autowired
    private IWfzGzffService wfzGzffService;
    //工资分摊服务层接口
    @Autowired
    private IWfzGzftService wfzGzftService;
    //工资计提服务层接口
    @Autowired
    private IWfzGzjtService wfzGzjtService;

    //组织成本中心服务层接口
    @Autowired
    private IWfzBaseunitService wfzBaseunitService;

    //人员服务层接口
    @Autowired
    private WfzPersonServiceImpl wfzPersonService;

    //薪酬总表计提工资福利服务层接口
    @Autowired
    private WfzJtgzflServiceImpl wfzJtgzflService;

    @Autowired
    private IWfzBankService wfzBankService;

    @Autowired
    private WfzBankMapper wfzBankMapper;





    public void splitBill(TWfzRemuneration tWfzRemuneration, List<TWfzRemunerationentry> tWfzRemunerationentryList, ArrayList<WfzGzff> gzffs) throws DataNullException {

        for (TWfzRemunerationentry tWfzRemunerationentry : tWfzRemunerationentryList) {

            String fpersonnumber = tWfzRemunerationentry.getFpersonnumber();

            //获取员工档案中的一级法人，将一级法人作为参数将分录划分开
            WfzPerson person = getPerson(fpersonnumber);

            if (person == null) {
                throw new DataNullException("未找到" + fpersonnumber + "员工数据");
            }
            String fsscompany = person.getFsscompany();
            String fsscost = person.getFsscost();
            String fcostcompany = person.getFcostcompany();
            String fgzffjrjg = person.getFgzffjrjg();

            WfzBaseunit unit = getUnitByGy(fsscompany);
            WfzBaseunit unitByGy = getUnitByGy(fsscost);
            WfzBaseunit compamyunitByGy1 = getUnitByGy(fcostcompany);

            if (unit == null) {
                throw new DataNullException("未找到" + fsscompany + "一级法人");
            }



            fsscompany = unit.getFnumber(); //eas编码
            String fvouType = unit.getFpzz(); //表头凭证字
            fsscost = unitByGy.getFnumber(); //eas成本中心
            String fcostname = unitByGy.getFname(); //成本中心民称
            fcostcompany = compamyunitByGy1.getFnumber(); //成本中心所属财务组织
            String fcosttype = unitByGy.getFcosttype(); //成本中心属性
            String fpzz = unitByGy.getFpzz(); //凭证字

            String fbanknumber = getBankNumBycomany(fsscompany, BillEnum.GZ.toString(), fgzffjrjg);
            if(fbanknumber==null){
                throw new DataNullException("没有"+fgzffjrjg+"的银行数据");
            }
            WfzGzff gzffByCompany = judIsBill(fsscompany, gzffs);//判断是否含有同一张单据,拿到相同组织的工资发放
            if (gzffByCompany!=null) {
                //查看是否融合 ,以成本中心和银行为维度进行融合
                List<WfzGzffentry> wfzGzffentryList = gzffByCompany.getWfzGzffentryList();
                Boolean flag = false;
                for (WfzGzffentry wfzGzffentry : wfzGzffentryList) {
                    String fyhzh = wfzGzffentry.getFyhzh();
                    String fcostnumber = wfzGzffentry.getFcostnumber();
                    if (fbanknumber.equals(fyhzh) && fsscost.equals(fcostnumber)) {
                        //融合
                        mergeGzff(wfzGzffentry,tWfzRemunerationentry);
                        String jsfs = billIssueUtil.Jsfs(fsscompany, fsscost);//组织间结算方式
                        if ("同组织下合并纳税成本中心".equals(jsfs)){
                            gzffByCompany.setFnscbzxrs(gzffByCompany.getFnscbzxrs().add(BigDecimal.ONE));
                        }
                        if ("同组织下是二级组织".equals(jsfs) || "非同组织".equals(jsfs)){
                            gzffByCompany.setFglf(gzffByCompany.getFglf().add(BigDecimal.ONE));
                        }
                        gzffByCompany.setFzrs(gzffByCompany.getFzrs().add(BigDecimal.ONE)); //总人数
                        flag = true;
                        break;
                    }
                }
                if (flag) {
                    continue;
                }
                // 未融合的单据则新增一条分录
                //新增一张单据//判断结算方式
                String jsfs = billIssueUtil.Jsfs(fsscompany, fsscost);//组织间结算方式
                //如果不存在新建一个工资发放队
                //拼接分录
                WfzGzffentry wfzGzffentry = new WfzGzffentry(); //
                addGzffEntry(tWfzRemunerationentry,wfzGzffentry,fsscompany,fsscost,fcostname,fcostcompany,fcosttype,fpzz,fgzffjrjg,fbanknumber);
                if ("同组织下合并纳税成本中心".equals(jsfs)){
                    gzffByCompany.setFnscbzxrs(gzffByCompany.getFnscbzxrs().add(BigDecimal.ONE));
                }
                if ("同组织下是二级组织".equals(jsfs) || "非同组织".equals(jsfs)){
                    gzffByCompany.setFglf(gzffByCompany.getFglf().add(BigDecimal.ONE));
                }
                gzffByCompany.getWfzGzffentryList().add(wfzGzffentry);
                int size = gzffByCompany.getWfzGzffentryList().size();
                gzffByCompany.setFzrs(BigDecimal.valueOf(size)); //总人数
            } else {
                //新增一张单据
                //判断结算方式
                String jsfs = billIssueUtil.Jsfs(fsscompany, fsscost);//组织间结算方式

                //如果不存在新建一个工资发放队
                WfzGzff wfzGzff = new WfzGzff();
                billIssueUtil.setBillNumber(wfzGzff);
                wfzGzff.setFperiod(tWfzRemuneration.getFperiod());
                wfzGzff.setFzrs(BigDecimal.ONE);
                if ("同组织下合并纳税成本中心".equals(jsfs)){
                    wfzGzff.setFnscbzxrs(BigDecimal.ONE);
                }
                if ("同组织下是二级组织".equals(jsfs) || "非同组织".equals(jsfs)){
                    wfzGzff.setFglf(BigDecimal.ONE);
                }

                wfzGzff.setFvourtype(fvouType); //凭证字
                wfzGzff.setFcreator("admin");
                wfzGzff.setFcreatetime(new Date());
                wfzGzff.setFcompany(fsscompany);
                wfzGzff.setFsourcebillid(tWfzRemuneration.getFid().toString());
                wfzGzff.setFstate("AUDIT");
                WfzGzffentry wfzGzffentry = new WfzGzffentry(); //
                ArrayList<WfzGzffentry> wfzGzffentries = new ArrayList<>();
                //拼接分录
                addGzffEntry(tWfzRemunerationentry,wfzGzffentry,fsscompany,fsscost,fcostname,fcostcompany,fcosttype,fpzz,fgzffjrjg,fbanknumber);
                wfzGzffentries.add(wfzGzffentry);
                //根据
                wfzGzff.setWfzGzffentryList(wfzGzffentries);

                gzffs.add(wfzGzff);
            }
        }
    }

    public WfzGzff judIsBill(String fssCompany,ArrayList<WfzGzff> gzffs){
        WfzGzff wfzGzff = null;
        for (WfzGzff gzff : gzffs) {
            String fcompany = gzff.getFcompany();
            if(fssCompany.equals(fcompany)){
                wfzGzff =gzff;
                break;
            }
        }
        return  wfzGzff;
    }

    /**
     * @// TODO: 2023/3/4 相同条件融合
     * @param wfzGzffentry 工资发放分录
     * @param tWfzRemunerationentry 薪酬总表分录
     */
    public void mergeGzff(WfzGzffentry wfzGzffentry,TWfzRemunerationentry tWfzRemunerationentry ){
        BigDecimal fyfgz = tWfzRemunerationentry.getFyfgz();
        BigDecimal fgryl = tWfzRemunerationentry.getFgryl();
        BigDecimal fgryy = tWfzRemunerationentry.getFgryy();
        BigDecimal fgrgjj = tWfzRemunerationentry.getFgrgjj();
        BigDecimal fgrsy = tWfzRemunerationentry.getFgrsy();
        BigDecimal fbkgryl = tWfzRemunerationentry.getFbkgryl();
        BigDecimal fbkgryy = tWfzRemunerationentry.getFbkgryy();
        BigDecimal fbkgrsy = tWfzRemunerationentry.getFbkgrsy();
        BigDecimal fbkgrzf = tWfzRemunerationentry.getFbkgrzf();
        BigDecimal fgrgfjf = tWfzRemunerationentry.getFgrgfjf();
        BigDecimal fjrfl = tWfzRemunerationentry.getFjrfl();
        BigDecimal fgwbnf = tWfzRemunerationentry.getFgwbnf();
        BigDecimal ffhbfl = tWfzRemunerationentry.getFfhbfl();
        BigDecimal fsssdf = tWfzRemunerationentry.getFsssdf();
        BigDecimal fzkk = tWfzRemunerationentry.getFzkk();
        BigDecimal fgrsds = tWfzRemunerationentry.getFgrsds();
        BigDecimal ffk = tWfzRemunerationentry.getFfk();

        BigDecimal sfhj = fyfgz.subtract(fgryl.add(fgryy).add(fgrsy).add(fgrgjj).add(fbkgryl).add(fbkgryy).add(fbkgrsy).add(fbkgrzf).add(fgrgfjf).add(fsssdf).add(fzkk).add(ffk).add(fgrsds));



        wfzGzffentry.setFyfgz(wfzGzffentry.getFyfgz().add(tWfzRemunerationentry.getFyfgz())); //应发工资
        wfzGzffentry.setFgryl(wfzGzffentry.getFgryl().add(tWfzRemunerationentry.getFgryl())); //个人养老
        wfzGzffentry.setFgryy(wfzGzffentry.getFgryy().add(tWfzRemunerationentry.getFgryy())); //个人医疗
        wfzGzffentry.setFgrsy(wfzGzffentry.getFgrsy().add(tWfzRemunerationentry.getFgrsy())); //个人失业
//        wfzGzffentry.setFgjj(wfzGzffentry.getFgjj().add(tWfzRemunerationentry.getFgjj())); //公积金
        wfzGzffentry.setFgrgjj(wfzGzffentry.getFgrgjj().add(tWfzRemunerationentry.getFgrgjj())); //个人公积金
        wfzGzffentry.setFbkgryl(wfzGzffentry.getFbkgryl().add(tWfzRemunerationentry.getFbkgryl())); //补扣个人养老
        wfzGzffentry.setFbkgryy(wfzGzffentry.getFbkgryy().add(tWfzRemunerationentry.getFbkgryy())); //补扣个人医疗
        wfzGzffentry.setFbkgrsy(wfzGzffentry.getFbkgrsy().add(tWfzRemunerationentry.getFbkgrsy())); //补扣个人失业
        wfzGzffentry.setFbkgrzf(wfzGzffentry.getFbkgrzf().add(tWfzRemunerationentry.getFbkgrzf()));   //补扣个人住房待定
        wfzGzffentry.setFgrgfjf(wfzGzffentry.getFgrgfjf().add(tWfzRemunerationentry.getFgrgfjf()));
        wfzGzffentry.setFjrfl(wfzGzffentry.getFjrfl().add(tWfzRemunerationentry.getFjrfl())); //节日福利
        wfzGzffentry.setFgwbnf(wfzGzffentry.getFgwbnf().add(tWfzRemunerationentry.getFgwbnf())); //高温/保暖费
        wfzGzffentry.setFfhbfl(wfzGzffentry.getFfhbfl().add(tWfzRemunerationentry.getFfhbfl())); //货币型福利
        wfzGzffentry.setFsssdf(wfzGzffentry.getFsssdf().add(tWfzRemunerationentry.getFsssdf())); //代扣宿舍水电费
        wfzGzffentry.setFzkk(wfzGzffentry.getFzkk().add(tWfzRemunerationentry.getFzkk())); //质扣款
        wfzGzffentry.setFgrsds(wfzGzffentry.getFgrsds().add(tWfzRemunerationentry.getFgrsds())); //个人所得税
        wfzGzffentry.setFfk(wfzGzffentry.getFfk().add(tWfzRemunerationentry.getFfk())); //罚款
        wfzGzffentry.setFsfhj(wfzGzffentry.getFsfhj().add(sfhj)); //实发合计
    }
    /**
     * @// TODO: 2023/3/4 新增一条工资发放分录
     * @param tWfzRemunerationentry 薪酬总表分录
     * @param fsscompany 一级法人
     * @param fsscost 成本中心
     * @param fcostname 成本中心名称
     * @param fcostcompany 成本中心所属财务组织
     * @param fcosttype 成本中心属性
     * @param fpzz 凭证字
     * @param fgzffjrjg 工资计提
     * @param fbanknumber 银行账号
     */
    public void addGzffEntry(TWfzRemunerationentry tWfzRemunerationentry,WfzGzffentry wfzGzffentry,String fsscompany,String fsscost,String fcostname,String fcostcompany,String fcosttype,String fpzz,String fgzffjrjg, String fbanknumber){
        String jsfs = billIssueUtil.Jsfs(fsscompany, fsscost);//组织间结算方式
        //如果不存在新建一个工资发放队
        //拼接分录
        BigDecimal fyfgz = tWfzRemunerationentry.getFyfgz();
        BigDecimal fgryl = tWfzRemunerationentry.getFgryl();
        BigDecimal fgryy = tWfzRemunerationentry.getFgryy();
        BigDecimal fgrgjj = tWfzRemunerationentry.getFgrgjj();
        BigDecimal fgrsy = tWfzRemunerationentry.getFgrsy();
        BigDecimal fbkgryl = tWfzRemunerationentry.getFbkgryl();
        BigDecimal fbkgryy = tWfzRemunerationentry.getFbkgryy();
        BigDecimal fbkgrsy = tWfzRemunerationentry.getFbkgrsy();
        BigDecimal fbkgrzf = tWfzRemunerationentry.getFbkgrzf();
        BigDecimal fgrgfjf = tWfzRemunerationentry.getFgrgfjf();
        BigDecimal fjrfl = tWfzRemunerationentry.getFjrfl();
        BigDecimal fgwbnf = tWfzRemunerationentry.getFgwbnf();
        BigDecimal ffhbfl = tWfzRemunerationentry.getFfhbfl();
        BigDecimal fsssdf = tWfzRemunerationentry.getFsssdf();
        BigDecimal fzkk = tWfzRemunerationentry.getFzkk();
        BigDecimal fgrsds = tWfzRemunerationentry.getFgrsds();
        BigDecimal ffk = tWfzRemunerationentry.getFfk();

        wfzGzffentry.setFyfgz(fyfgz); //应发工资
        wfzGzffentry.setFgryl(fgryl); //个人养老
        wfzGzffentry.setFgryy(fgryy); //个人医疗
        wfzGzffentry.setFgrsy(fgrsy); //个人失业
//        wfzGzffentry.setFgjj(tWfzRemunerationentry.getFgrsy()); //公积金
        wfzGzffentry.setFgrgjj(fgrgjj); //个人公积金
        wfzGzffentry.setFbkgryl(fbkgryl); //补扣个人养老
        wfzGzffentry.setFbkgryy(fbkgryy); //补扣个人医疗
        wfzGzffentry.setFbkgrsy(fbkgrsy); //补扣个人失业
        wfzGzffentry.setFbkgrzf(fbkgrzf);   //补扣个人住房待定
        wfzGzffentry.setFgrgfjf(fgrgfjf);   //补扣个人公费经费待定
        wfzGzffentry.setFjrfl(fjrfl); //节日福利
        wfzGzffentry.setFgwbnf(fgwbnf); //高温/保暖费
        wfzGzffentry.setFfhbfl(ffhbfl); //货币型福利
        wfzGzffentry.setFsssdf(fsssdf); //代扣宿舍水电费
        wfzGzffentry.setFzkk(fzkk); //质扣款
        wfzGzffentry.setFgrsds(fgrsds); //个人所得税
        wfzGzffentry.setFfk(ffk); //罚款
        //实发合计单据计算，除（节日福利，高温/保暖费，代扣宿舍水电费），应付-除（节日福利，高温/保暖费，代扣宿舍水电费）其他金额
        BigDecimal sfhj = fyfgz.subtract(fgryl.add(fgryy).add(fgrsy).add(fgrgjj).add(fbkgryl).add(fbkgryy).add(fbkgrsy).add(fbkgrzf).add(fgrgfjf).add(fsssdf).add(fzkk).add(ffk).add(fgrsds));
        wfzGzffentry.setFsfhj(sfhj); //实发合计

        wfzGzffentry.setFcostname(fcostname);
        wfzGzffentry.setFcostnumber(fsscost);
        wfzGzffentry.setFcostcompany(fcostcompany); //c成本中心所属财务组织
        wfzGzffentry.setFjsfs(jsfs);  //结算方式

        wfzGzffentry.setFcbzxxz(fcosttype); //成本中心属性
        wfzGzffentry.setFvourtype(fpzz); //凭证字

        wfzGzffentry.setFcbzxffjg(fgzffjrjg); //金融机构
        wfzGzffentry.setFyhzh(fbanknumber); //银行账号
        wfzGzffentry.setFsscwzz(fcostcompany);
    }


    public WfzPerson getPerson(String personCode){
        WfzPerson wfzPerson = new WfzPerson();
        WfzPerson person = null;
        wfzPerson.setFnumber(personCode);
        List<WfzPerson> wfzPeople = wfzPersonService.selectWfzPersonList(wfzPerson);
        if (wfzPeople.size() > 0){
            person = wfzPeople.get(0);
        }

        return person;
    }

    /**
     * todo 通过盖雅编码还原EAS编码
     * @param unitCode 盖雅编码
     * @return
     *
     */
    public WfzBaseunit getUnitByGy(String unitCode){

        WfzBaseunit wfzBaseunit = new WfzBaseunit();
        wfzBaseunit.setFgynumber(unitCode);
        WfzBaseunit baseunit = null;
        List<WfzBaseunit> wfzBaseunits = wfzBaseunitService.selectWfzBaseunitList(wfzBaseunit);
        if (wfzBaseunits.size()>0){
            baseunit = wfzBaseunits.get(0);
        }
        return baseunit;
    }


    /**
     * @// TODO: 2023/3/4 根据金融机构和财务组织获取工资银行账号
     * @param fsscompany
     * @return
     */
    public String getBankNumBycomany(String fsscompany,String BillType,String fgzffjrjg){
        WfzBank wfzBank = new WfzBank();
        String fbanknumber = null;
        wfzBank.setFcompanynumber(fsscompany);
        wfzBank.setFtype(BillType);
        List<WfzBank> wfzBanks = wfzBankService.selectWfzBankList(wfzBank);
        if(wfzBanks.size()>0){
            WfzBank bank = wfzBanks.get(0);
            List<WfzBankentry> wfzBankentries = wfzBankMapper.selectBankEntry(wfzBanks.get(0).getFid(), fgzffjrjg);
            if(wfzBankentries.size()>=0){
                WfzBankentry wfzBankentry = wfzBankentries.get(0);
                 fbanknumber = wfzBankentry.getFbanknumber();
            }
        }
        return fbanknumber;
    }



}
